package com.scwatch.core.fulltext;


import com.scwatch.common.fulltext.LuceneException;
import com.scwatch.core.domain.Special;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.NumericField;
import org.apache.lucene.index.Term;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.TermQuery;
import org.springframework.util.NumberUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import static org.apache.lucene.document.Field.Index.ANALYZED;
import static org.apache.lucene.document.Field.Index.NOT_ANALYZED;
import static org.apache.lucene.document.Field.Store.NO;
import static org.apache.lucene.document.Field.Store.YES;
import static org.apache.lucene.search.BooleanClause.Occur.*;
import static org.apache.lucene.util.Version.LUCENE_36;


/**
 * 专题实体的全文检索转换类
 *
 */
public class FSpecial {
    public static final String ID = "id";
    public static final String SITE_ID = "siteId";
    public static final String TITLE = "title";
    public static final String CREATEDATE="createDate";
    public static final String PRIORITY="priority";
    /**
     *  判断索引类型：专题索引
     */
    public static final String TYPE="type";
    public static final String TYPE_DEFALT_VALUE="FSpecial";

    public static List<Integer> idsFromDoc(List<Document> docList) {
        if (!docList.isEmpty()) {
            List<Integer> ids = new ArrayList<Integer>(docList.size());
            for (Document doc : docList) {
                ids.add(NumberUtils.parseNumber(doc.get(ID), Integer.class));
            }
            return ids;
        } else {
            return Collections.emptyList();
        }
    }

    public static List<Integer> idsFromString(List<String> idList) {
        if (!idList.isEmpty()) {
            List<Integer> ids = new ArrayList<Integer>(idList.size());
            for (String id : idList) {
                ids.add(NumberUtils.parseNumber(id, Integer.class));
            }
            return ids;
        } else {
            return Collections.emptyList();
        }
    }

    public static Term id(Integer id) {
        return new Term(FNode.ID, String.valueOf(id));
    }

    public static Document doc(Special spec) {
        if(spec==null){
            return null;
        }
        Document doc = new Document();
        String id = String.valueOf(spec.getId());
        doc.add(new Field(ID, id, YES, NOT_ANALYZED));

        String siteId = String.valueOf(spec.getSite().getId());
        doc.add(new Field(SITE_ID, siteId, NO, NOT_ANALYZED));

        String title =spec.getTitle();
        if (StringUtils.isNotBlank(title)) {
            doc.add(new Field(TITLE, title, YES, NOT_ANALYZED));
        }

        NumericField createDate = new NumericField(CREATEDATE);
        doc.add(createDate.setLongValue(spec.getCreationDate().getTime()));

        NumericField priority = new NumericField(PRIORITY);
        doc.add(priority.setIntValue(spec.getPriority()));

        doc.add(new Field(TYPE,TYPE_DEFALT_VALUE, NO, NOT_ANALYZED));

        return doc;
    }

    public static Query query(Analyzer analyzer, Integer[] siteIds,Integer[] excludeId,Integer[] includeId,String title) {
        try {
            BooleanQuery query = new BooleanQuery();
            if (ArrayUtils.isNotEmpty(siteIds)) {
                BooleanQuery qy = new BooleanQuery();
                for (Integer id : siteIds) {
                    String s = String.valueOf(id);
                    qy.add(new TermQuery(new Term(SITE_ID, s)), SHOULD);
                }
                query.add(qy, MUST);
            }

            if (ArrayUtils.isNotEmpty(excludeId)) {
                for (Integer id : excludeId) {
                    query.add(new TermQuery(id(id)), MUST_NOT);
                }
            }

            if (ArrayUtils.isNotEmpty(includeId)) {
                BooleanQuery qy = new BooleanQuery();
                for (Integer id : includeId) {
                    query.add(new TermQuery(id(id)), SHOULD);
                }
                query.add(qy, MUST);
            }

            if (StringUtils.isNotBlank(title)) {
                title = QueryParser.escape(title);
                QueryParser p = new QueryParser(LUCENE_36, TITLE, analyzer);
                query.add(p.parse(title), MUST);
            }

            //判断索引类型：专题索引
            BooleanQuery typeQy = new BooleanQuery();
            typeQy.add(new TermQuery(new Term(TYPE, TYPE_DEFALT_VALUE)), SHOULD);
            query.add(typeQy, MUST);

            return query;
        } catch (Exception e) {
            throw new LuceneException("Error during create query.", e);
        }
    }


}
